package com.jeestudio.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Created by shuttle on 18/7/17.
 */
public class OKHttpUtil {

    public static final Logger LOGGER          = LoggerFactory.getLogger(OKHttpUtil.class);

    public final static int       CONNECT_TIMEOUT = 30;
    public final static int       READ_TIMEOUT    = 30;
    public final static int       WRITE_TIMEOUT   = 30;

    public final static int       SHORT_CONNECT_TIMEOUT = 3;
    public final static int       SHORT_READ_TIMEOUT    = 3;
    public final static int       SHORT_WRITE_TIMEOUT   = 3;
    public static final MediaType JSON_TYPE       = MediaType.parse("application/json; charset=utf-8");

    public static String sendGetTimeOutShort(String url, Map<String, String> header) {
        OkHttpClient client = getConnClientShort();
        FormBody.Builder builder = new FormBody.Builder();

        String headerName = "user-agent";
        String headeValue = "nodata";

        FormBody body = builder.build();
        Request request = null;
        Request.Builder builder2 = new Request.Builder().url(url).get();//build();
        if(null != header){
            Set<String> keySet = header.keySet();
            Iterator<String> iterator = keySet.iterator();
            while(iterator.hasNext()){
                String key = iterator.next();
                String value = header.get(key);
                builder2.addHeader(key, value);
            }
        }
        request = builder2.build();
        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                return response.body().string();
            } else {
                LOGGER.info("请求响应异常,{}", response.toString());
                return null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String sendGet(String url, Map<String, String> header) {
        OkHttpClient client = getConnClient();
        FormBody.Builder builder = new FormBody.Builder();

        String headerName = "user-agent";
        String headeValue = "nodata";

        FormBody body = builder.build();
        Request request = null;
        Request.Builder builder2 = new Request.Builder().url(url).get();//build();
        if(null != header){
            Set<String> keySet = header.keySet();
            Iterator<String> iterator = keySet.iterator();
            while(iterator.hasNext()){
                String key = iterator.next();
                String value = header.get(key);
                builder2.addHeader(key, value);
            }
        }
        request = builder2.build();
        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                return response.body().string();
            } else {
                LOGGER.info("请求响应异常,{}", response.toString());
                return null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String sendGet(String url) {
        return sendGet(url,null);
    }

    public static String sendPost(String url, Map<String, String> paramMap) {
        return sendPost(url, paramMap, null);
    }

    public static String sendPost(String url, Map<String, String> paramMap, Map<String, String> header) {
        OkHttpClient client = getConnClient();
        FormBody.Builder builder = new FormBody.Builder();
        if (paramMap != null) {
            String paramName = null;
            String paramValue = null;
            for (Map.Entry<String, String> entry : paramMap.entrySet()) {
                paramName = entry.getKey();
                paramValue = entry.getValue();
                builder.add(paramName, paramValue);
            }
        }
        String headerName = "user-agent";
        String headeValue = "nodata";
        if (header != null) {
            for (Map.Entry<String, String> entry : header.entrySet()) {
                headerName = entry.getKey();
                headeValue = entry.getValue();
            }
        }
        FormBody body = builder.build();
        Request request = new Request.Builder().url(url).addHeader(headerName, headeValue).post(body).build();
        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                return response.body().string();
            } else {
                LOGGER.info("请求响应异常,{}", response.toString());
                return "服务异常";
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @Description: 发送jso参数
     * 没有写请求header
     * @return
     * @author: yqx
     * @date: 2016年12月24日 下午2:30:16
     */
    public static String sendPostJson(String url, Map<String, String> paramMap) {
        OkHttpClient client = getConnClient();
        String jsonString = JSONObject.toJSONString(paramMap);
        RequestBody body = RequestBody.create(JSON_TYPE, jsonString);
        Request request = new Request.Builder().url(url).post(body).build();
        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                return response.body().string();
            } else {
                LOGGER.info("请求响应异常,{}", response.toString());
                return "服务异常";
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "请求超时";
        }
    }

    /**
     * @Description: 发送jso参数
     * 没有写请求header
     * @return
     * @author: yqx
     * @date: 2016年12月24日 下午2:30:16
     */
    public static String sendPostJson(String url, String jsonString) {
        OkHttpClient client = getConnClient();
        RequestBody body = RequestBody.create(JSON_TYPE, jsonString);
        Request request = new Request.Builder().url(url).post(body).build();
        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                return response.body().string();
            } else {
                LOGGER.info("请求响应异常,{}", response.toString());
                return "服务异常";
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "请求超时";
        }
    }

    /**
     * @Description: 传入的对象，返回对象
     * @param url 请求url
     * @param e 传入参数
     * @param t 响应对象
     * @return
     * @author: yqx
     * @date: 2016年12月24日 下午3:58:56
     */
    public static <T, E> T sendPostJson(String url, E e, Class<T> t) {
        OkHttpClient client = getConnClient();
        T object = null;
        String paramJson = JSON.toJSONString(e);
        RequestBody body = RequestBody.create(JSON_TYPE, paramJson);
        Request request = new Request.Builder().url(url).post(body).build();
        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                String string = response.body().string();
                JSONObject parseObject = JSON.parseObject(string);
                object = JSON.toJavaObject(parseObject, t);
                return object;
            } else {
                LOGGER.info("请求响应异常,{}", response.toString());
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return object;
    }

    /**
     * @Description: postJson 参数是对象，返回string
     * @param url 请求url
     * @param t  传入参数
     * @return
     * @author: yqx
     * @date: 2016年12月26日 上午10:38:50
     */
    public static <T> String sendPostJson(String url, T t) {
        OkHttpClient client = getConnClient();
        String paramJson = JSON.toJSONString(t);
        RequestBody body = RequestBody.create(JSON_TYPE, paramJson);
        Request request = new Request.Builder().url(url).post(body).build();
        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                String string = response.body().string();
                return string;
            } else {
                LOGGER.info("请求响应异常,{}", response.toString());
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("code", 500);
                jsonObject.put("message", "服务请求异常");
                return jsonObject.toString();
            }
        } catch (Exception ex) {
            addExpectionLog("sendPostJson请求异常", ex);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code", 500);
            jsonObject.put("message", "服务请求超时");
            return jsonObject.toString();
        }
    }

    private static void addExpectionLog(String exceptionDesc, Exception e) {
        StringWriter sw = new StringWriter();
        e.printStackTrace(new PrintWriter(sw, true));
        LOGGER.error(exceptionDesc + "--->" + sw.toString());
    }

    public static OkHttpClient getConnClient() {
        OkHttpClient client = getClient();
        return client;
    }

    public static OkHttpClient getConnClientShort() {
        OkHttpClient client = getClientShort();
        return client;
    }

    private static final class InnerOKHttp {
        private static OkHttpClient client = new OkHttpClient.Builder().readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
                .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS).connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS).build();

        private static OkHttpClient clientShort = new OkHttpClient.Builder().readTimeout(SHORT_READ_TIMEOUT, TimeUnit.SECONDS)
                .writeTimeout(SHORT_WRITE_TIMEOUT, TimeUnit.SECONDS).connectTimeout(SHORT_CONNECT_TIMEOUT, TimeUnit.SECONDS).build();
    }

    public static OkHttpClient getClient() {
        return InnerOKHttp.client;
    }

    public static OkHttpClient getClientShort() {
        return InnerOKHttp.clientShort;
    }
}
